﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using System.Threading;

using ZetaPrints.ZetaClient.Data;
using ZetaPrints.ZetaClient.Data.Repository;
using ZetaPrints.ZetaClient.Data.Repository.Linq;
using ZetaPrints.ZetaClient.Shared;

namespace ZetaPrints.ZetaClient.Business
{
    /// <summary>
    /// This is the manager of the highest level
    /// system. Here is where everything is managed
    /// </summary>
    public class ZetaManager : BaseManager
    {
        #region private attributes
        /// <summary>
        /// These are the sites which are selected at the moment
        /// </summary>
        private List<SiteManager> _siteManagerList;
        #endregion


        #region public properties
        /// <summary>
        /// Checks to see if the thread is alive
        /// </summary>
        /// <returns></returns>
        public override bool AreThreadsAlive
        {
            get
            {
                bool areThreadsAlive = ThreadManager.AreThreadsAlive;

                if (!areThreadsAlive)
                {
                    foreach (SiteManager siteManager in _siteManagerList)
                    {
                        if (siteManager.AreThreadsAlive)
                        {
                            areThreadsAlive = true;
                            break;
                        }
                    }
                }

                return areThreadsAlive;
            }
        }
        #endregion


        #region constructors
        public ZetaManager()
        {
            _siteManagerList = new List<SiteManager>();
            FetchSiteManagers();
        }
        #endregion


        #region private methods
        /// <summary>
        /// Gets the list of all sites
        /// </summary>
        /// <returns></returns>
        private void FetchSiteManagers()
        {
            /// clear up the list
            _siteManagerList = new List<SiteManager>();

            /// get all the sites from the database
            List<Site> sites = _dataRepositoryManager.FetchSites();

            foreach (Site site in sites)
            {
                /// Create the site
                SiteManager siteManager = new SiteManager(site);

                /// connect to the system of messaging
                siteManager.OnEventMessenger += new EventHandler<EventMessenger>(base_OnEventMessenger);

                _siteManagerList.Add(siteManager);
            }
        }
        #endregion


        #region public methods
        /// <summary>
        /// This will cause all the threads to stop
        /// </summary>
        public override void AbortAllThreads()
        {
            /// stop all the children first
            foreach (SiteManager siteManager in _siteManagerList)
            {
                siteManager.AbortAllThreads();
            }

            /// now itself
            ThreadManager.AbortAllThreads();
        }       
        #region site
        /// <summary>
        /// Returns true if the site is selected.
        /// </summary>
        /// <param name="siteId"></param>
        /// <returns></returns>
        public bool IsSiteSelected(int siteId)
        {
            bool siteSelected = false;

            var countFound = (from siteManagerItem in _siteManagerList
                                where siteManagerItem.SiteEntry.SiteId == siteId && siteManagerItem.Selected
                                select siteManagerItem).Count();

            if (countFound > 0)
            {
                siteSelected = true;
            }

            return siteSelected;
        }
        /// <summary>
        /// Get the download for all the active sites for a 
        /// date
        /// </summary>
        /// <param name="startDateTime"></param>
        public void DownloadOrderList(DateTime startDateTime)
        {
            /// get the sites that are selected
            List<SiteManager> siteManagerListSelection = GetSelectedSiteManagerList();

            foreach (SiteManager siteManager in siteManagerListSelection)
            {
                siteManager.DownloadOrders(startDateTime);
            }
        }
        /// <summary>
        /// The current site been used by the system. All the 
        /// sites supported will be displayed
        /// </summary>
        public List<SiteManager> GetSiteManagerList()
        {
            return _siteManagerList;
        }
        /// <summary>
        /// The list of Sites
        /// </summary>
        /// <returns></returns>
        public List<Site> GetSiteList()
        {
            List<Site> siteList = new List<Site>();

            foreach (SiteManager siteManager in _siteManagerList)
            {
                siteList.Add(siteManager.SiteEntry);
            }

            return siteList;
        }
        /// <summary>
        /// The current site been used by the system. All the 
        /// sites supported will be displayed
        /// </summary>
        public List<SiteManager> GetSelectedSiteManagerList()
        {
            List<SiteManager> siteSelectedList = new List<SiteManager>();

            /// gets only the selected sites
            var siteManagerListSelection = from siteItem in _siteManagerList
                                           where siteItem.Selected == true
                                           select siteItem;

            foreach (SiteManager siteManager in siteManagerListSelection)
            {
                siteSelectedList.Add(siteManager);
            }

            return siteSelectedList;
        }
        /// <summary>
        /// Out of all the selected sites we will get the oldest date
        /// to do our download for.
        /// </summary>
        /// <returns></returns>
        public DateTime LatestOrderDateTimeOfSelected()
        {
            DateTime returnDateTime = new DateTime(2000, 1, 1, 0, 0, 0);

            var site = (from siteItem in _siteManagerList
                        where siteItem.Selected
                        orderby siteItem.LatestOrderDateTime ascending
                        select siteItem.LatestOrderDateTime).Take(1);

            if (site.Count() > 0)
            {
                returnDateTime = (DateTime)site.First();
            }

            return returnDateTime;
        }
        /// <summary>
        /// Adds a site to be selected in the system
        /// </summary>
        public void AddSiteToSelected(string siteName)
        {
            foreach (SiteManager siteManager in _siteManagerList)
            {
                if (siteManager.SiteEntry.SiteName == siteName)
                {
                    siteManager.Selected = true;
                    siteManager.FetchOrders();
                    break;
                }
            }
        }
        /// <summary>
        /// Removes a site from the selection system
        /// </summary>
        /// <param name="siteName"></param>
        public void RemoveSiteFromSelection(string siteName)
        {
            foreach(SiteManager siteManager in _siteManagerList)
            {
                if (siteManager.SiteEntry.SiteName == siteName)
                {
                    siteManager.Selected = false;
                    break;
                }
            }
        }
        /// <summary>
        /// Saves the site list
        /// </summary>
        /// <param name="siteList"></param>
        public void SaveSites(List<SiteManager> siteList)
        {
            foreach (SiteManager siteManager in siteList)
            {
                _dataRepositoryManager.SaveSite(siteManager.SiteEntry);
            }
        }
        /// <summary>
        /// Saves the site list
        /// </summary>
        /// <param name="siteList"></param>
        public void SaveSites(List<Site> siteList)
        {
            foreach (Site site in siteList)
            {
                _dataRepositoryManager.SaveSite(site);
            }

            /// 
            FetchSiteManagers();
        }
        /// <summary>
        /// Deletes the sites
        /// </summary>
        /// <param name="siteList"></param>
        public void DeleteSite(List<SiteManager> siteManagerList)
        {
            foreach (SiteManager removeSiteManager in siteManagerList)
            {
                for (int count = 0; count < _siteManagerList.Count; )
                {
                    /// does the name match, if yes remove it.
                    if (removeSiteManager.SiteEntry.SiteName == _siteManagerList[count].SiteEntry.SiteName)
                    {
                        _siteManagerList[count].DeleteSite();
                        _siteManagerList.RemoveAt(count);
                        break;
                    }
                    else
                    {
                        count++;
                    }
                }
            }
        }
        /// <summary>
        /// Deletes the sites
        /// </summary>
        /// <param name="siteList"></param>
        public void DeleteSite(List<Site> siteList)
        {
            List<SiteManager> deleteSiteManager = new List<SiteManager>();

            foreach (Site site in siteList)
            {
                foreach (SiteManager siteManager in _siteManagerList)
                {
                    if (site.SiteName == siteManager.SiteEntry.SiteName)
                    {
                        deleteSiteManager.Add(siteManager);
                        break;
                    }
                }
            }

            DeleteSite(deleteSiteManager);
        }
        /// <summary>
        /// Returns the OrderManager for all the selected
        /// sites
        /// </summary>
        /// <returns></returns>
        public List<OrderManager> GetSelectedOrderManagerList()
        {
            /// create a list of order managers for us to return ot the screen
            List<OrderManager> orderManagerList = new List<OrderManager>();

            List<SiteManager> siteManagerList = GetSelectedSiteManagerList();

            foreach (SiteManager siteManager in siteManagerList)
            {
                orderManagerList.AddRange(siteManager.OrderManagerList);
            }

            return orderManagerList;
        }
        #endregion
        #region order status
        public List<OrderStatus> FetchOrderStatusList()
        {
            return _dataRepositoryManager.FetchOrderStatusList();
        }
        #endregion
        #region order
        /// <summary>
        /// Gets a OrderManager that is contained already in one
        /// of the sites within this class. This will not search 
        /// database, the data better be in memory.
        /// </summary>
        /// <param name="siteName"></param>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public OrderManager GetOrderManager(string siteName, Guid orderId)
        {
            OrderManager orderManager = null;

            var siteManagerData = (from siteManagerItem in GetSelectedSiteManagerList()
                                   where siteManagerItem.SiteEntry.SiteName == siteName
                                   select siteManagerItem).Take(1);

            if( siteManagerData.Count() > 0 )
            {
                orderManager = siteManagerData.First().GetOrderManager(orderId);
            }

            return orderManager;
        }
        #endregion
        #endregion
    }
}
